home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / editors / stevie3a.1 < prev    next >
Text File  |  1989-03-15  |  65KB  |  2,843 lines

  1. Path: xanth!lll-winken!ames!mailrus!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i040:  stevie - vi-like text editor v35a, Part01/06
  5. Message-ID: <12213@swan.ulowell.edu>
  6. Date: 15 Mar 89 14:56:10 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2832
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: grwalter@watcgl.waterloo.edu (Fred Walter)
  12. Posting-number: Volume 89, Issue 40
  13. Archive-name: editors/stevie35a.1
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    MAKE_TAGS
  23. #    Makefile
  24. #    README
  25. #    TODO
  26. #    amiga.h
  27. #    ascii.h
  28. #    bsd.c
  29. #    bsd.h
  30. #    dec.c
  31. #    dos.c
  32. #    dos.h
  33. #    env.h
  34. #    inc.c
  35. #    keymap.h
  36. #    linefunc.c
  37. #    macros.h
  38. #    makefile.amiga.lattice
  39. #    makefile.bsd
  40. #    makefile.dos
  41. #    makefile.mwc
  42. #    makefile.os2
  43. #    makefile.tos
  44. #    makefile.usg
  45. #    mark.c
  46. #    mk.c
  47. #    os2.h
  48. #    param.c
  49. #    param.h
  50. #    porting.doc
  51. #    raw.c
  52. #    regexp.h
  53. #    regmagic.h
  54. #    regsub.c
  55. #    sendpacket.c
  56. #    source.doc
  57. #    tos.h
  58. #    unix.c
  59. #    unix.h
  60. #    updateNs.c
  61. #    updateRs.c
  62. # This archive created: Tue Mar 14 14:40:09 1989
  63. cat << \SHAR_EOF > MAKE_TAGS
  64. /ctags/ctags -t    alloc.c charset.c cmdline.c dec.c edit.c
  65. /ctags/ctags -t -a fileio.c help.c inc.c linefunc.c main.c mark.c
  66. /ctags/ctags -t -a misccmds.c normal.c param.c raw.c screen.c
  67. /ctags/ctags -t -a search.c sendpacket.c updateNs.c
  68. /ctags/ctags -t -a updateRs.c ascii.h keymap.h
  69. /ctags/ctags -t -a macros.h param.h stevie.h term.h mk.c
  70.  
  71. /ctags/ctags -t -a amiga.h amiga.c
  72. SHAR_EOF
  73. cat << \SHAR_EOF > Makefile
  74. #
  75. # Makefile for Lattice C 5.0 on Amiga
  76. #
  77.  
  78. .c.o:
  79.     lc $(CFLAGS) $<
  80.  
  81. CFLAGS = -cu -ma -O
  82. LINKFLAGS = NODEBUG
  83. LIBS = lib:lc.lib
  84.  
  85. MACH=    amiga.o raw.o sendpacket.o
  86.  
  87. OBJ1=    main.o edit.o linefunc.o normal.o cmdline.o charset.o
  88. OBJ2=    updateRs.o misccmds.o help.o dec.o inc.o search.o alloc.o
  89. OBJ3=    mk.o regexp.o regsub.o version.o
  90. OBJ4=    updateNs.o mark.o screen.o fileio.o param.o
  91.  
  92. OBJ= $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(MACH)
  93.  
  94. all: stevie
  95.     say "done all"
  96.  
  97. stevie: $(OBJ)
  98.     BLINK TO stevie FROM lib:cres.o $(OBJ) LIBRARY $(LIBS) $(LINKFLAGS)
  99.  
  100. clean:
  101.     delete $(OBJ1)
  102.     delete $(OBJ2)
  103.     delete $(OBJ3)
  104.     delete $(OBJ4)
  105.     delete $(MACH)
  106.     delete stevie
  107. SHAR_EOF
  108. cat << \SHAR_EOF > README
  109. STEVIE Source Release
  110.  
  111. This is a source release of the STEVIE editor, a public domain clone
  112. of the UNIX editor 'vi'. The program was originally developed for the
  113. Atari ST, but has been ported to UNIX, OS/2, BSD 4.3 and the Amiga as well.
  114.  
  115. There are currently two divergent versions of STEVIE. This version is the one
  116. that was ported to the Amiga and then worked on by me (G. R. Walter). The other
  117. one Tony Andrews continued to work on. My version is faster in some respects
  118. then his version, and his version does a couple of things mine doesn't. 
  119.  
  120. The files included in this release are:
  121.  
  122. README
  123.     This file.
  124.  
  125. stevie.doc
  126.     Reference manual for STEVIE. Assumes familiarity with vi.
  127.  
  128. source.doc
  129.     Quick overview of the major data structures used.
  130.  
  131. porting.doc
  132.     Tips for porting STEVIE to other systems.
  133.  
  134. makefile.dos
  135. makefile.os2
  136. makefile.usg
  137. makefile.tos
  138. makefile.bsd
  139. makefile.amiga.lattice
  140.     Makefiles for MS DOS, OS/2, UNIX System V, Atari ST, BSD 4.3 UNIX and
  141. the Amiga respectively.
  142.  
  143. raw.c
  144. sendpacket.c
  145. amiga.c
  146. amiga.h
  147. bsd.c
  148. bsd.h
  149. dos.c
  150. dos.h
  151. os2.c
  152. os2.h
  153. unix.c
  154. unix.h
  155. tos.c
  156. tos.h
  157.     System-dependent routines for the same.
  158.  
  159. alloc.c ascii.h cmdline.c edit.c fileio.c help.c charset.c
  160. keymap.h linefunc.c main.c mark.c misccmds.c normal.c param.c
  161. regexp.c regsub.c version.c regexp.h regmagic.h
  162. param.h ptrfunc.c screen.c search.c stevie.h term.h macros.h
  163.  
  164.     C source and header files for STEVIE.
  165.  
  166. To compile STEVIE for one of the provided systems:
  167.  
  168.     1. Compile the regular expression library and install as
  169.        appropriate for your system.
  170.  
  171.     2. Edit the file 'env.h' to set the system defines as needed.
  172.  
  173.     3. Check the makefile for your system, and modify as needed.
  174.  
  175.     4. Compile.
  176.  
  177. NOTE: implicit in the design is the assumption that char's are unsigned. Thus
  178.       if your compiler assumes different by default, change the default or
  179.       you may have to change the source.
  180.  
  181. Good Luck...
  182.  
  183. Tony Andrews            March  12, 1988
  184. G. R. (Fred) Walter     August 14, 1988
  185. SHAR_EOF
  186. cat << \SHAR_EOF > TODO
  187. To Do
  188. -----
  189.  
  190. - Change the static buffers for insert/undo/redo/undoundo/etc to dynamic
  191.   buffers.
  192.  
  193. - Add #'d and named buffers.
  194.  
  195. - Add 'R' and 'U'.
  196.  
  197. - Add 'set sw' option.
  198.  
  199. - In cmdline.c make get_range() give the appropriate error messages when it
  200.   gets a bad line range.
  201.  
  202. - Add & (do last search and replace on current line) and :[range]&
  203.   (do last search and replace on the range of lines).
  204.  
  205. - change the screen code so that number of columns is always a multiple
  206.   of four. Then add assembler routines for copying (to be used in
  207.   updateNextscreen()) that copy longs (4 bytes at a time). This will 
  208.   speed up things even more.
  209. SHAR_EOF
  210. cat << \SHAR_EOF > amiga.h
  211. /*
  212.  * Amiga Machine-dependent routines. 
  213.  */
  214.  
  215. extern FILE *raw_io;
  216. extern int   new_window;
  217.  
  218. int  inchar();
  219. void flushbuf();
  220. void outchar();
  221. void outstr();
  222. void beep();
  223. void windinit(), windexit(), windgoto();
  224. void delay();
  225. void sleep();
  226. SHAR_EOF
  227. cat << \SHAR_EOF > ascii.h
  228. /*
  229.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  230.  *
  231.  * Code Contributions By : Tim Thompson           twitch!tjt
  232.  *                         Tony Andrews           onecom!wldrdg!tony 
  233.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  234.  */
  235.  
  236. /*
  237.  * Definitions of various common control characters 
  238.  */
  239.  
  240. #define    NUL            '\000'
  241. #define    BS            '\010'
  242. #define    BS_STR            "\010"
  243. #define    TAB            '\011'
  244. #define    NL            '\012'
  245. #define    NL_STR            "\012"
  246. #define    CR            '\015'
  247. #define    ESC            '\033'
  248. #define    ESC_STR            "\033"
  249.  
  250. #define    UNDO_SHIFTJ        '\333'
  251. #define    UNDO_SHIFTJ_STR        "\333"
  252.  
  253. #define    ENABLE_REDRAWING    '\334'
  254. #define    ENABLE_REDRAWING_STR    "\334"
  255.  
  256. #define    CTRL(x)    ((x) & 0x1f)
  257. SHAR_EOF
  258. cat << \SHAR_EOF > bsd.c
  259. /*
  260.  * System-dependent routines for BSD 4.3 UNIX 
  261.  */
  262.  
  263. #include "stevie.h"
  264. #include <sgtty.h>
  265.  
  266. /*
  267.  * inchar() - get a character from the keyboard 
  268.  */
  269. int
  270. inchar()
  271. {
  272.     int             c;
  273.  
  274.     fflush(stdout);        /* flush any pending output */
  275.  
  276.     c = getchar();
  277.  
  278.     return c;
  279. }
  280.  
  281. void
  282. outstr(s)
  283.     char           *s;
  284. {
  285.     while (*s)
  286.     outchar(*s++);
  287. }
  288.  
  289. void
  290. beep()
  291. {
  292.     if (RedrawingDisabled)
  293.     return;
  294.  
  295.     outchar('\007');
  296. }
  297.  
  298. void
  299. delay()
  300. {
  301.     sleep(1);
  302. }
  303.  
  304. static struct sgttyb ostate;
  305.  
  306. void
  307. windinit()
  308. {
  309.     char           *getenv();
  310.     char           *term;
  311.     struct sgttyb   nstate;
  312.  
  313.     term = getenv("TERM");
  314.     if (!term) {
  315.     fprintf(stderr, "Invalid terminal type '%s'\n", term);
  316.     exit(1);
  317.     }
  318.     if ((strncmp(term, "vt", 2) != 0) && (strncmp(term, "kd", 2) != 0)) {
  319.     fprintf(stderr, "Invalid terminal type '%s'\n", term);
  320.     exit(1);
  321.     }
  322.     Columns = 80;
  323.     P(P_LI) = Rows = 24;
  324.  
  325.     /*
  326.      * Go into cbreak mode 
  327.      */
  328.     ioctl(1, (long) TIOCGETP, (char *) &ostate);
  329.     nstate = ostate;
  330.     nstate.sg_flags = nstate.sg_flags & ~(ECHO | CRMOD) | CBREAK;
  331.     ioctl(1, (long) TIOCSETP, (char *) &nstate);
  332. }
  333.  
  334. void
  335. windexit(r)
  336.     int             r;
  337. {
  338.     fflush(stdout);
  339.  
  340.     ioctl(0, (long) TIOCSETP, (char *) &ostate);
  341.  
  342.     exit(r);
  343. }
  344.  
  345. void
  346. windgoto(r, c)
  347.     int             c;
  348.     int             r;
  349. {
  350.     r++;
  351.     c++;
  352.  
  353.     outstr("\033[");
  354.     if (r >= 10)
  355.     outchar((char) (r / 10 + '0'));
  356.     outchar((char) (r % 10 + '0'));
  357.     outchar(';');
  358.     if (c >= 10)
  359.     outchar((char) (c / 10 + '0'));
  360.     outchar((char) (c % 10 + '0'));
  361.     outchar('H');
  362. }
  363.  
  364. FILE           *
  365. fopenb(fname, mode)
  366.     char           *fname;
  367.     char           *mode;
  368. {
  369.     return fopen(fname, mode);
  370. }
  371. SHAR_EOF
  372. cat << \SHAR_EOF > bsd.h
  373. /*
  374.  * BSD 4.3 Machine-dependent routines. 
  375.  */
  376.  
  377. int inchar();
  378. #define outchar(c) putchar(c)
  379. void outstr(), beep();
  380. #define remove(path) unlink(path)
  381. int rename();
  382. void windinit(), windexit(), windgoto();
  383. void delay();
  384. SHAR_EOF
  385. cat << \SHAR_EOF > dec.c
  386. /*
  387.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  388.  *
  389.  * Code Contributions By : Tim Thompson           twitch!tjt
  390.  *                         Tony Andrews           onecom!wldrdg!tony 
  391.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  392.  */
  393.  
  394. #include "stevie.h"
  395.  
  396. /*
  397.  * dec(p) 
  398.  *
  399.  * Decrement the line pointer 'p' crossing line boundaries as necessary. Return
  400.  * 1 when crossing a line, -1 when at start of file, 0 otherwise. 
  401.  */
  402. int
  403. dec(lp)
  404.     register LPtr  *lp;
  405. {
  406.     if (lp->index > 0) {    /* still within line */
  407.     lp->index--;
  408.     return 0;
  409.     }
  410.     if (lp->linep->prev != Filetop->linep) {    /* there is a prior line */
  411.     lp->linep = lp->linep->prev;
  412.     lp->index = strlen(lp->linep->s);
  413.     return 1;
  414.     }
  415.     lp->index = 0;        /* stick at first char */
  416.     return -1;            /* at start of file */
  417. }
  418. SHAR_EOF
  419. cat << \SHAR_EOF > dos.c
  420. static char     RCSid[] =
  421. "$Header: dos.c,v 1.1 88/05/03 14:22:16 tony Exp $";
  422.  
  423. /*
  424.  * DOS System-dependent routines.
  425.  *
  426.  * System-specific code for MS-DOS. This has been tested with
  427.  * MSDOS 3.3 on an AT. Also, the console driver "nansi.sys" is
  428.  * required.
  429.  *
  430.  * $Log:    dos.c,v $
  431.  * Revision 1.1  88/05/03  14:22:16  tony
  432.  * Initial revision
  433.  * 
  434.  *
  435.  */
  436.  
  437. #include "stevie.h"
  438.  
  439. /*
  440.  * inchar() - get a character from the keyboard
  441.  */
  442. int
  443. inchar()
  444. {
  445.     int             c;
  446.  
  447.     for (;; beep()) {        /* loop until we get a valid character */
  448.  
  449.     flushbuf();        /* flush any pending output */
  450.  
  451.     switch (c = getch()) {
  452.       case 0x1e:
  453.         return K_CGRAVE;
  454.       case 0:        /* special key */
  455.         if (State != NORMAL) {
  456.         c = getch();    /* throw away next char */
  457.         continue;    /* and loop for another char */
  458.         }
  459.         switch (c = getch()) {
  460.           case 0x50:
  461.         return K_DARROW;
  462.           case 0x48:
  463.         return K_UARROW;
  464.           case 0x4b:
  465.         return K_LARROW;
  466.           case 0x4d:
  467.         return K_RARROW;
  468.           case 0x52:
  469.         return K_INSERT;
  470.           case 0x47:
  471.         stuffReadbuff("1G");
  472.         return -1;
  473.           case 0x4f:
  474.         stuffReadbuff("G");
  475.         return -1;
  476.           case 0x51:
  477.         stuffReadbuff(mkstr(CTRL('F')));
  478.         return -1;
  479.           case 0x49:
  480.         stuffReadbuff(mkstr(CTRL('B')));
  481.         return -1;
  482.         /*
  483.          * Hard-code some useful function key macros. 
  484.          */
  485.           case 0x3b:    /* F1 */
  486.         stuffReadbuff(":p\n");
  487.         return -1;
  488.           case 0x54:    /* SF1 */
  489.         stuffReadbuff(":p!\n");
  490.         return -1;
  491.           case 0x3c:    /* F2 */
  492.         stuffReadbuff(":n\n");
  493.         return -1;
  494.           case 0x55:    /* SF2 */
  495.         stuffReadbuff(":n!\n");
  496.         return -1;
  497.           case 0x3d:    /* F3 */
  498.         stuffReadbuff(":e #\n");
  499.         return -1;
  500.           case 0x3e:    /* F4 */
  501.         stuffReadbuff(":rew\n");
  502.         return -1;
  503.           case 0x57:    /* SF4 */
  504.         stuffReadbuff(":rew!\n");
  505.         return -1;
  506.           case 0x3f:    /* F5 */
  507.         stuffReadbuff("[[");
  508.         return -1;
  509.           case 0x40:    /* F6 */
  510.         stuffReadbuff("]]");
  511.         return -1;
  512.           case 0x41:    /* F7 */
  513.         stuffReadbuff("<<");
  514.         return -1;
  515.           case 0x42:    /* F8 */
  516.         stuffReadbuff(">>");
  517.         return -1;
  518.           case 0x43:    /* F9 */
  519.         stuffReadbuff(":x\n");
  520.         return -1;
  521.           case 0x44:    /* F10 */
  522.         stuffReadbuff(":help\n");
  523.         return -1;
  524.           default:
  525.         break;
  526.         }
  527.         break;
  528.  
  529.       default:
  530.         return c;
  531.     }
  532.     }
  533. }
  534.  
  535. #define    BSIZE    2048
  536. static char     outbuf[BSIZE];
  537. static int      bpos = 0;
  538.  
  539. flushbuf()
  540. {
  541.     if (bpos != 0)
  542.     write(1, outbuf, bpos);
  543.     bpos = 0;
  544. }
  545.  
  546. /*
  547.  * Macro to output a character. Used within this file for speed.
  548.  */
  549. #define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  550.  
  551. /*
  552.  * Function version for use outside this file.
  553.  */
  554. void
  555. outchar(c)
  556.     register char   c;
  557. {
  558.     outbuf[bpos++] = c;
  559.     if (bpos >= BSIZE)
  560.     flushbuf();
  561. }
  562.  
  563. static char     cell[2] = {0, 7};
  564.  
  565. /*
  566.  * outstr(s) - write a string to the console
  567.  */
  568. void
  569. outstr(s)
  570.     register char  *s;
  571. {
  572.     while (*s) {
  573.     outone(*s++);
  574.     }
  575. }
  576.  
  577. void
  578. beep()
  579. {
  580.     if (RedrawingDisabled)
  581.     return;
  582.  
  583.     outone('\007');
  584. }
  585.  
  586. void
  587. sleep(n)
  588.     int             n;
  589. {
  590.     /*
  591.      * Should do something reasonable here. 
  592.      */
  593. }
  594.  
  595. void
  596. delay()
  597. {
  598.     long            l;
  599.  
  600.     flushbuf();
  601.     /*
  602.      * Should do something better here... 
  603.      */
  604.     for (l = 0; l < 5000; l++);
  605. }
  606.  
  607. void
  608. windinit()
  609. {
  610.     Columns = 80;
  611.     P(P_LI) = Rows = 25;
  612. }
  613.  
  614. void
  615. windexit(r)
  616.     int             r;
  617. {
  618.     flushbuf();
  619.     exit(r);
  620. }
  621.  
  622. void
  623. windgoto(r, c)
  624.     register int    r, c;
  625. {
  626.     r += 1;
  627.     c += 1;
  628.  
  629.     /*
  630.      * Check for overflow once, to save time. 
  631.      */
  632.     if (bpos + 8 >= BSIZE)
  633.     flushbuf();
  634.  
  635.     outbuf[bpos++] = '\033';
  636.     outbuf[bpos++] = '[';
  637.     if (r >= 10)
  638.     outbuf[bpos++] = r / 10 + '0';
  639.     outbuf[bpos++] = r % 10 + '0';
  640.     outbuf[bpos++] = ';';
  641.     if (c >= 10)
  642.     outbuf[bpos++] = c / 10 + '0';
  643.     outbuf[bpos++] = c % 10 + '0';
  644.     outbuf[bpos++] = 'H';
  645. }
  646.  
  647. FILE           *
  648. fopenb(fname, mode)
  649.     char           *fname;
  650.     char           *mode;
  651. {
  652.     FILE           *fopen();
  653.     char            modestr[16];
  654.  
  655.     sprintf(modestr, "%sb", mode);
  656.     return fopen(fname, modestr);
  657. }
  658. SHAR_EOF
  659. cat << \SHAR_EOF > dos.h
  660. /*
  661.  * MS DOS Machine-dependent routines. 
  662.  */
  663.  
  664. int  inchar();
  665. void outchar();
  666. void outstr();
  667. void beep();
  668. void windinit();
  669. void windexit();
  670. void windgoto();
  671. void delay();
  672. void sleep();
  673. SHAR_EOF
  674. cat << \SHAR_EOF > env.h
  675. /*
  676.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  677.  *
  678.  * Code Contributions By : Tim Thompson           twitch!tjt
  679.  *                         Tony Andrews           onecom!wldrdg!tony 
  680.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  681.  */
  682.  
  683. /*
  684.  * The defines in this file establish the environment we're compiling
  685.  * in. Set these appropriately before compiling the editor.
  686.  */
  687.  
  688. /*
  689.  * One (and only 1) of the following defines should be uncommented. Most of
  690.  * the code is pretty machine-independent. Machine dependent code goes in a
  691.  * file like tos.c or unix.c. The only other place where machine dependent
  692.  * code goes is term.h for escape sequences. 
  693.  */
  694.  
  695. #ifndef AMIGA
  696. #define    ATARI            Atari ST */
  697. /* #define    UNIX        System V */
  698. /* #define    BSD        BSD 4.3 */
  699. /* #define    OS2        Microsoft OS/2 */
  700. /* #define    DOS        MS DOS 3.3 */
  701. /* #define    AMIGA        Amiga */
  702. #endif
  703.  
  704. /*
  705.  * If ATARI is defined, one of the following compilers must be selected. 
  706.  */
  707. #ifdef    ATARI
  708. #define MWC            Mark William's C 3.0.9 */
  709. /* #define    MEGAMAX        Megamax Compiler */
  710. /* #define    ALCYON        Alcyon C compiler */
  711.  
  712. # ifdef MWC
  713. #  define AppendNumberToUndoUndobuff     XX1
  714. #  define AppendPositionToUndoUndobuff    XX2
  715. #  define FOPENB
  716. # endif
  717.  
  718. # ifdef MEGAMAX
  719. #  define FOPENB
  720. # endif
  721. #endif
  722.  
  723. /*
  724.  * If HELP is defined, the :help command shows a vi command summary. 
  725.  */
  726. #define    HELP            /* enable help command */
  727.  
  728. /*
  729.  * STRCSPN should be defined if the target system doesn't have the
  730.  * routine strcspn() available. See regexp.c for details.
  731.  */
  732.  
  733. #ifdef    ATARI
  734. #define    STRCSPN
  735. #endif
  736. SHAR_EOF
  737. cat << \SHAR_EOF > inc.c
  738. /*
  739.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  740.  *
  741.  * Code Contributions By : Tim Thompson           twitch!tjt
  742.  *                         Tony Andrews           onecom!wldrdg!tony 
  743.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  744.  */
  745.  
  746. #include "stevie.h"
  747.  
  748. /*
  749.  * inc(p) 
  750.  *
  751.  * Increment the line pointer 'p' crossing line boundaries as necessary. Return
  752.  * 1 when crossing a line, -1 when at end of file, 0 otherwise. 
  753.  */
  754. int
  755. inc(lp)
  756.     register LPtr  *lp;
  757. {
  758.     register char  *p = &(lp->linep->s[lp->index]);
  759.  
  760.     if (*p != NUL) {        /* still within line */
  761.     lp->index++;
  762.     return ((p[1] != NUL) ? 0 : 1);
  763.     }
  764.     if (lp->linep->next != Fileend->linep) {    /* there is a next line */
  765.     lp->index = 0;
  766.     lp->linep = lp->linep->next;
  767.     return 1;
  768.     }
  769.     return -1;
  770. }
  771. SHAR_EOF
  772. cat << \SHAR_EOF > keymap.h
  773. /*
  774.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  775.  *
  776.  * Code Contributions By : Tim Thompson           twitch!tjt
  777.  *                         Tony Andrews           onecom!wldrdg!tony 
  778.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  779.  */
  780.  
  781. /*
  782.  * Keycode definitions for special keys 
  783.  *
  784.  * On systems that have any of these keys, the routine 'inchar' in the
  785.  * machine-dependent code should return one of the codes here. 
  786.  */
  787.  
  788. #define    K_CGRAVE    0x1e    /* control grave accent */
  789.  
  790. #define    K_HELP        0x80
  791. #define    K_UNDO        0x81
  792. #define    K_INSERT    0x82
  793. #define    K_HOME        0x83
  794. #define    K_UARROW    0x84
  795. #define    K_DARROW    0x85
  796. #define    K_LARROW    0x86
  797. #define    K_RARROW    0x87
  798. #define    K_SUARROW    0x88
  799. #define    K_SDARROW    0x89
  800. #define    K_SLARROW    0x8a
  801. #define    K_SRARROW    0x8b
  802.  
  803. #define    K_F1        0x8c    /* function keys */
  804. #define    K_F2        0x8d
  805. #define    K_F3        0x8e
  806. #define    K_F4        0x8f
  807. #define    K_F5        0x90
  808. #define    K_F6        0x91
  809. #define    K_F7        0x92
  810. #define    K_F8        0x93
  811. #define    K_F9        0x94
  812. #define    K_F10        0x95
  813.  
  814. #define    K_SF1        0x96    /* shifted function keys */
  815. #define    K_SF2        0x97
  816. #define    K_SF3        0x98
  817. #define    K_SF4        0x99
  818. #define    K_SF5        0x9a
  819. #define    K_SF6        0x9b
  820. #define    K_SF7        0x9c
  821. #define    K_SF8        0x9d
  822. #define    K_SF9        0x9e
  823. #define    K_SF10        0x9f
  824. SHAR_EOF
  825. cat << \SHAR_EOF > linefunc.c
  826. /*
  827.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  828.  *
  829.  * Code Contributions By : Tim Thompson           twitch!tjt
  830.  *                         Tony Andrews           onecom!wldrdg!tony 
  831.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  832.  */
  833.  
  834. #include "stevie.h"
  835.  
  836. /*
  837.  * nextline(curr) 
  838.  *
  839.  * Return a pointer to the beginning of the next line after the one referenced
  840.  * by 'curr'. Return NULL if there is no next line (at EOF). 
  841.  */
  842.  
  843. LPtr           *
  844. nextline(curr)
  845.     LPtr           *curr;
  846. {
  847.     static LPtr     next;
  848.  
  849.     if (curr != NULL) {
  850.     if (curr->linep->next != Fileend->linep) {
  851.         next.index = 0;
  852.         next.linep = curr->linep->next;
  853.         return &next;
  854.     }
  855.     }
  856.     return (LPtr *) NULL;
  857. }
  858.  
  859. /*
  860.  * prevline(curr) 
  861.  *
  862.  * Return a pointer to the beginning of the line before the one referenced by
  863.  * 'curr'. Return NULL if there is no prior line. 
  864.  */
  865.  
  866. LPtr           *
  867. prevline(curr)
  868.     LPtr           *curr;
  869. {
  870.     static LPtr     prev;
  871.  
  872.     if (curr != NULL) {
  873.     if (curr->linep->prev != Filetop->linep) {
  874.         prev.index = 0;
  875.         prev.linep = curr->linep->prev;
  876.         return &prev;
  877.     }
  878.     }
  879.     return (LPtr *) NULL;
  880. }
  881.  
  882. /*
  883.  * coladvance(p,col) 
  884.  *
  885.  * Try to advance to the specified column, starting at p. 
  886.  */
  887.  
  888. LPtr           *
  889. coladvance(p, col)
  890.     LPtr           *p;
  891.     int             col;
  892. {
  893.     static LPtr     lp;
  894.     int             c, in;
  895.  
  896.     lp.linep = p->linep;
  897.     lp.index = p->index;
  898.  
  899.     /* If we're on a blank ('\n' only) line, we can't do anything */
  900.     if (lp.linep->s[lp.index] == '\0')
  901.     return &lp;
  902.     /* try to advance to the specified column */
  903.     for (c = 0; col-- > 0; c++) {
  904.     /* Count a tab for what it's worth (if list mode not on) */
  905.     if (gchar(&lp) == TAB && !P(P_LS)) {
  906.         in = ((P(P_TS) - 1) - c % P(P_TS));
  907.         col -= in;
  908.         c += in;
  909.     }
  910.     /* Don't go past the end of */
  911.     /* the file or the line. */
  912.     if (inc(&lp)) {
  913.         dec(&lp);
  914.         break;
  915.     }
  916.     }
  917.     return &lp;
  918. }
  919. SHAR_EOF
  920. cat << \SHAR_EOF > macros.h
  921. /*
  922.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  923.  *
  924.  * Code Contributions By : Tim Thompson           twitch!tjt
  925.  *                         Tony Andrews           onecom!wldrdg!tony 
  926.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  927.  */
  928.  
  929. /*
  930.  * gchar(lp) - get the character at position "lp" 
  931.  */
  932. #define gchar(lp) ((lp)->linep->s[(lp)->index])
  933.  
  934. /*
  935.  * pchar(lp, c) - put character 'c' at position 'lp' 
  936.  */
  937. #define pchar(lp, c) ((lp)->linep->s[(lp)->index] = (c))
  938.  
  939. /*
  940.  * pswap(a, b) - swap two position pointers 
  941.  */
  942. #define pswap(a, b) { LPtr pswaptmp; pswaptmp = a; a = b; b = pswaptmp; }
  943.  
  944. /*
  945.  * Position comparisons 
  946.  */
  947. #define lt(a, b) ((LINEOF(a) != LINEOF(b)) \
  948.                    ? (LINEOF(a) < LINEOF(b)) : ((a)->index < (b)->index))
  949.  
  950. #define ltoreq(a, b) ((LINEOF(a) != LINEOF(b)) \
  951.                    ? (LINEOF(a) < LINEOF(b)) : ((a)->index <= (b)->index))
  952.  
  953. #define gt(a, b) ((LINEOF(a) != LINEOF(b)) \
  954.                    ? (LINEOF(a) > LINEOF(b)) : ((a)->index > (b)->index))
  955.  
  956. #define gtoreq(a, b) ((LINEOF(a) != LINEOF(b)) \
  957.                    ? (LINEOF(a) > LINEOF(b)) : ((a)->index >= (b)->index))
  958.  
  959. #define equal(a, b) (((a)->linep == (b)->linep) && ((a)->index == (b)->index))
  960.  
  961. /*
  962.  * anyinput
  963.  *
  964.  * Return non-zero if input is pending.
  965.  */
  966. #define anyinput() (Readbuffptr != NULL)
  967.  
  968. /*
  969.  * buf1line() - return TRUE if there is only one line in file buffer
  970.  */
  971. #define buf1line() (Filemem->linep->next == Fileend->linep)
  972.  
  973. /*
  974.  * bufempty() - return TRUE if the file buffer is empty 
  975.  */
  976. #define bufempty() (buf1line() && Filemem->linep->s[0] == NUL)
  977.  
  978. /*
  979.  * lineempty() - return TRUE if the line is empty 
  980.  */
  981. #define lineempty(p) ((p)->linep->s[0] == NUL)
  982.  
  983. /*
  984.  * startofline() - return TRUE if the given position is at start of line 
  985.  */
  986. #define startofline(p) ((p)->index == 0)
  987.  
  988. /*
  989.  * endofline() - return TRUE if the given position is at end of line 
  990.  *
  991.  * This routine will probably never be called with a position resting on the NUL
  992.  * byte, but handle it correctly in case it happens. 
  993.  */
  994. #define endofline(p) \
  995.      ((p)->linep->s[(p)->index] == NUL || (p)->linep->s[(p)->index + 1] == NUL)
  996.  
  997. /*
  998.  * RowNumber() - return the row number (if no UndoInProgress)
  999.  */
  1000. #define RowNumber(p) (UndoInProgress ? 0 : cntllines(Filemem, (p)))
  1001. SHAR_EOF
  1002. cat << \SHAR_EOF > makefile.amiga.lattice
  1003. #
  1004. # Makefile for Lattice C 5.0 on Amiga
  1005. #
  1006.  
  1007. .c.o:
  1008.     lc $(CFLAGS) $<
  1009.  
  1010. CFLAGS = -cu -ma -O
  1011. LINKFLAGS = NODEBUG
  1012. LIBS = lib:lc.lib
  1013.  
  1014. MACH=    amiga.o raw.o sendpacket.o
  1015.  
  1016. OBJ1=    main.o edit.o linefunc.o normal.o cmdline.o charset.o
  1017. OBJ2=    updateRs.o misccmds.o help.o dec.o inc.o search.o alloc.o
  1018. OBJ3=    mk.o regexp.o regsub.o version.o
  1019. OBJ4=    updateNs.o mark.o screen.o fileio.o param.o
  1020.  
  1021. OBJ= $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(MACH)
  1022.  
  1023. all: stevie
  1024.     say "done all"
  1025.  
  1026. stevie: $(OBJ)
  1027.     BLINK TO stevie FROM lib:cres.o $(OBJ) LIBRARY $(LIBS) $(LINKFLAGS)
  1028.  
  1029. clean:
  1030.     delete $(OBJ1)
  1031.     delete $(OBJ2)
  1032.     delete $(OBJ3)
  1033.     delete $(OBJ4)
  1034.     delete $(MACH)
  1035.     delete stevie
  1036. SHAR_EOF
  1037. cat << \SHAR_EOF > makefile.bsd
  1038. #
  1039. # Makefile for BSD 4.3 UNIX
  1040. #
  1041.  
  1042. CFLAGS = -pg -g
  1043. LINTFLAGS = 
  1044.  
  1045. MACHOBJ=    bsd.o
  1046. MACHSRC=    bsd.c
  1047.  
  1048. SRC=    main.c edit.c linefunc.c normal.c cmdline.c charset.c \
  1049.     updateRs.c misccmds.c help.c dec.c inc.c search.c alloc.c \
  1050.     mk.c regexp.c regsub.c version.c \
  1051.     updateNs.c mark.c screen.c fileio.c param.c $(MACHSRC)
  1052.  
  1053. OBJ=    main.o edit.o linefunc.o normal.o cmdline.o charset.o \
  1054.     updateRs.o misccmds.o help.o dec.o inc.o search.o alloc.o \
  1055.     mk.o regexp.o regsub.o version.o \
  1056.     updateNs.o mark.o screen.o fileio.o param.o $(MACHOBJ)
  1057.  
  1058. all : stevie
  1059.  
  1060. stevie : $(OBJ)
  1061.     $(CC) $(OBJ) $(CFLAGS) -o stevie
  1062.  
  1063. lint:
  1064.     lint $(LINTFLAGS) $(SRC)
  1065.  
  1066. clean :
  1067.     rm -f *.out *.o core stevie *.BAK
  1068. SHAR_EOF
  1069. cat << \SHAR_EOF > makefile.dos
  1070. #
  1071. # Makefile for DOS
  1072. #
  1073. # This makefile is set up for Microsoft C 5.1
  1074. #
  1075.  
  1076. #
  1077. # Compact model lets us edit large files, but keep small model code
  1078. #
  1079. MODEL= /AC
  1080. CFLAGS = $(MODEL)
  1081.  
  1082. MACH=    dos.obj
  1083.  
  1084. OBJ=    main.obj edit.obj linefunc.obj normal.obj cmdline.obj charset.obj \
  1085.     mk.obj updateRs.obj regexp.obj regsub.obj version.obj \
  1086.     misccmds.obj help.obj dec.obj inc.obj search.obj alloc.obj \
  1087.     updateNs.obj mark.obj screen.obj fileio.obj param.obj $(MACH)
  1088.  
  1089. all:    stevie.exe
  1090.  
  1091. main.obj:    main.c
  1092.     cl -c $(CFLAGS) main.c
  1093.  
  1094. updateRs.obj:    updateRs.c
  1095.     cl -c $(CFLAGS) updateRs.c
  1096.  
  1097. mk.obj:    mk.c
  1098.     cl -c $(CFLAGS) mk.c
  1099.  
  1100. regexp.obj:    regexp.c
  1101.     cl -c $(CFLAGS) regexp.c
  1102.  
  1103. regsub.obj:    regsub.c
  1104.     cl -c $(CFLAGS) regsub.c
  1105.  
  1106. version.obj:    version.c
  1107.     cl -c $(CFLAGS) version.c
  1108.  
  1109. alloc.obj : alloc.c
  1110.     cl -c $(CFLAGS) alloc.c
  1111.  
  1112. edit.obj : edit.c
  1113.     cl -c $(CFLAGS) edit.c
  1114.  
  1115. updateNs.obj : updateNs.c
  1116.     cl -c $(CFLAGS) updateNs.c
  1117.  
  1118. linefunc.obj : linefunc.c
  1119.     cl -c $(CFLAGS) linefunc.c
  1120.  
  1121. normal.obj : normal.c
  1122.     cl -c $(CFLAGS) normal.c
  1123.  
  1124. cmdline.obj : cmdline.c
  1125.     cl -c $(CFLAGS) cmdline.c
  1126.  
  1127. charset.obj : charset.c
  1128.     cl -c $(CFLAGS) charset.c
  1129.  
  1130. misccmds.obj : misccmds.c
  1131.     cl -c $(CFLAGS) misccmds.c
  1132.  
  1133. help.obj : help.c
  1134.     cl -c $(CFLAGS) help.c
  1135.  
  1136. dec.obj : dec.c
  1137.     cl -c $(CFLAGS) dec.c
  1138.  
  1139. inc.obj : inc.c
  1140.     cl -c $(CFLAGS) inc.c
  1141.  
  1142. search.obj : search.c
  1143.     cl -c $(CFLAGS) search.c
  1144.  
  1145. mark.obj : mark.c
  1146.     cl -c $(CFLAGS) mark.c
  1147.  
  1148. screen.obj : screen.c
  1149.     cl -c $(CFLAGS) screen.c
  1150.  
  1151. fileio.obj : fileio.c
  1152.     cl -c $(CFLAGS) fileio.c
  1153.  
  1154. param.obj : param.c
  1155.     cl -c $(CFLAGS) param.c
  1156.  
  1157. os2.obj : os2.c
  1158.     cl -c $(CFLAGS) os2.c
  1159.  
  1160. stevie.exe : $(OBJ)
  1161.     cl $(MODEL) *.obj c:\lib\setargv.obj -o stevie.exe /F 6000 -link /NOE
  1162. SHAR_EOF
  1163. cat << \SHAR_EOF > makefile.mwc
  1164. #
  1165. #
  1166. #
  1167. # Makefile for Mark Williams C
  1168. #
  1169. CFLAGS = -O -VPEEP 
  1170. LDFLAGS = -s -x -v
  1171. LINKER=ld
  1172.  
  1173. OBJ1=    main.o edit.o linefunc.o normal.o cmdline.o charset.o \
  1174.     updatere.o misccmds.o help.o dec.o inc.o 
  1175. OBJ2=    alloc.o search.o mk.o regexp.o regsub.o version.o updatene.o \
  1176.     mark.o screen.o fileio.o param.o tos.o
  1177.  
  1178. SRC=    main.c edit.c linefunc.c normal.c cmdline.c charset.c \
  1179.     updatere.c misccmds.c help.c dec.c inc.c search.c alloc.c \
  1180.     mk.c regexp.c regsub.c version.c \
  1181.     updatene.c mark.c screen.c fileio.c param.c \
  1182.     tos.c
  1183.  
  1184.  
  1185. all : stevie.ttp
  1186.  
  1187. stevie.a: $(OBJ1) $(OBJ2)
  1188.     ar rv stevie.a $(OBJ1)
  1189.     ar rv stevie.a $(OBJ2)
  1190.  
  1191. stevie.ttp:    stevie.a
  1192.     cc stevie.a $(LIBS) -o stevie.ttp
  1193. SHAR_EOF
  1194. cat << \SHAR_EOF > makefile.os2
  1195. #
  1196. # Makefile for OS/2
  1197. #
  1198. # The make command with OS/2 is really stupid.
  1199. #
  1200.  
  1201. #
  1202. # Compact model lets us edit large files, but keep small model code
  1203. #
  1204. MODEL= -AC
  1205. CFLAGS = $(MODEL) -I..\regexp -J
  1206.  
  1207. MACH=    os2.obj
  1208.  
  1209. OBJ=    main.obj edit.obj linefunc.obj normal.obj cmdline.obj charset.obj \
  1210.     mk.obj updateRs.obj regexp.obj regsub.obj version.obj \
  1211.     misccmds.obj help.obj dec.obj inc.obj search.obj alloc.obj \
  1212.     updateNs.obj mark.obj screen.obj fileio.obj param.obj $(MACH)
  1213.  
  1214. all:    stevie.exe
  1215.  
  1216. main.obj:    main.c
  1217.     cl -c $(CFLAGS) main.c
  1218.  
  1219. updateRs.obj:    updateRs.c
  1220.     cl -c $(CFLAGS) updateRs.c
  1221.  
  1222. mk.obj:    mk.c
  1223.     cl -c $(CFLAGS) mk.c
  1224.  
  1225. regexp.obj:    regexp.c
  1226.     cl -c $(CFLAGS) regexp.c
  1227.  
  1228. regsub.obj:    regsub.c
  1229.     cl -c $(CFLAGS) regsub.c
  1230.  
  1231. version.obj:    version.c
  1232.     cl -c $(CFLAGS) version.c
  1233.  
  1234. alloc.obj : alloc.c
  1235.     cl -c $(CFLAGS) alloc.c
  1236.  
  1237. edit.obj : edit.c
  1238.     cl -c $(CFLAGS) edit.c
  1239.  
  1240. updateNs.obj : updateNs.c
  1241.     cl -c $(CFLAGS) updateNs.c
  1242.  
  1243. linefunc.obj : linefunc.c
  1244.     cl -c $(CFLAGS) linefunc.c
  1245.  
  1246. normal.obj : normal.c
  1247.     cl -c $(CFLAGS) normal.c
  1248.  
  1249. cmdline.obj : cmdline.c
  1250.     cl -c $(CFLAGS) cmdline.c
  1251.  
  1252. charset.obj : charset.c
  1253.     cl -c $(CFLAGS) charset.c
  1254.  
  1255. misccmds.obj : misccmds.c
  1256.     cl -c $(CFLAGS) misccmds.c
  1257.  
  1258. help.obj : help.c
  1259.     cl -c $(CFLAGS) help.c
  1260.  
  1261. dec.obj : dec.c
  1262.     cl -c $(CFLAGS) dec.c
  1263.  
  1264. inc.obj : inc.c
  1265.     cl -c $(CFLAGS) inc.c
  1266.  
  1267. search.obj : search.c
  1268.     cl -c $(CFLAGS) search.c
  1269.  
  1270. mark.obj : mark.c
  1271.     cl -c $(CFLAGS) mark.c
  1272.  
  1273. screen.obj : screen.c
  1274.     cl -c $(CFLAGS) screen.c
  1275.  
  1276. fileio.obj : fileio.c
  1277.     cl -c $(CFLAGS) fileio.c
  1278.  
  1279. param.obj : param.c
  1280.     cl -c $(CFLAGS) param.c
  1281.  
  1282. os2.obj : os2.c
  1283.     cl -c $(CFLAGS) os2.c
  1284.  
  1285. stevie.exe : $(OBJ)
  1286.     cl $(MODEL) *.obj $(LIBS) -o stevie.exe
  1287.     copy stevie.exe rstevie.exe
  1288.     bind rstevie.exe \lib\api.lib \lib\doscalls.lib
  1289. SHAR_EOF
  1290. cat << \SHAR_EOF > makefile.tos
  1291. #
  1292. # Makefile for the Atari ST - Megamax C compiler
  1293. #
  1294.  
  1295. CFLAGS = -DMEGAMAX
  1296.  
  1297. #    Megamax rule
  1298. .c.o:
  1299.     mmcc $(CFLAGS) $<
  1300.     mmimp $*.o
  1301.     mmlib rv vi.lib $*.o
  1302.  
  1303. MACH=    tos.o
  1304.  
  1305. OBJ=    main.o edit.o linefunc.o normal.o cmdline.o charset.o \
  1306.     updateRs.o misccmds.o help.o dec.o inc.o search.o alloc.o \
  1307.     mk.o regexp.o regsub.o version.o \
  1308.     updateNs.o mark.o screen.o fileio.o param.o $(MACH)
  1309.  
  1310. all : stevie.ttp
  1311.  
  1312. stevie.ttp : $(OBJ)
  1313.     $(LINKER) vi.lib $(LIBS) -o stevie.ttp
  1314.  
  1315. clean :
  1316.     $(RM) $(OBJ) vi.lib
  1317. SHAR_EOF
  1318. cat << \SHAR_EOF > makefile.usg
  1319. #
  1320. # Makefile for UNIX (System V)
  1321. #
  1322.  
  1323. CFLAGS = -O
  1324.  
  1325. MACH=    unix.o
  1326.  
  1327. OBJ=    main.o edit.o linefunc.o normal.o cmdline.o charset.o \
  1328.     updateRs.o misccmds.o help.o dec.o inc.o search.o alloc.o \
  1329.     mk.o regexp.o regsub.o version.o \
  1330.     updateNs.o mark.o screen.o fileio.o param.o $(MACH)
  1331.  
  1332. all : stevie
  1333.  
  1334. stevie : $(OBJ)
  1335.     $(CC) $(OBJ) $(LIBS) -o stevie
  1336.  
  1337. clean :
  1338.     rm $(OBJ)
  1339. SHAR_EOF
  1340. cat << \SHAR_EOF > mark.c
  1341. /*
  1342.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  1343.  *
  1344.  * Code Contributions By : Tim Thompson           twitch!tjt
  1345.  *                         Tony Andrews           onecom!wldrdg!tony 
  1346.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1347.  */
  1348.  
  1349. #include "stevie.h"
  1350.  
  1351. #ifdef    MEGAMAX
  1352. overlay "mark"
  1353. #endif
  1354.  
  1355. /*
  1356.  * This file contains routines to maintain and manipulate marks. 
  1357.  */
  1358.  
  1359. #define    NMARKS    10        /* max. # of marks that can be saved */
  1360.  
  1361. struct mark {
  1362.     char            name;
  1363.     LPtr            pos;
  1364. };
  1365.  
  1366. static struct mark mlist[NMARKS];
  1367. static struct mark pcmark;    /* previous context mark */
  1368. static bool_t   pcvalid = FALSE;/* true if pcmark is valid */
  1369.  
  1370. /*
  1371.  * setmark(c) - set mark 'c' at current cursor position 
  1372.  *
  1373.  * Returns TRUE on success, FALSE if no room for mark or bad name given. 
  1374.  */
  1375. bool_t
  1376. setmark(c)
  1377.     char            c;
  1378. {
  1379.     int             i;
  1380.  
  1381.     if (!isalpha(c))
  1382.     return FALSE;
  1383.  
  1384.     /*
  1385.      * If there is already a mark of this name, then just use the existing
  1386.      * mark entry. 
  1387.      */
  1388.     for (i = 0; i < NMARKS; i++) {
  1389.     if (mlist[i].name == c) {
  1390.         mlist[i].pos = *Curschar;
  1391.         return TRUE;
  1392.     }
  1393.     }
  1394.  
  1395.     /*
  1396.      * There wasn't a mark of the given name, so find a free slot 
  1397.      */
  1398.     for (i = 0; i < NMARKS; i++) {
  1399.     if (mlist[i].name == NUL) {    /* got a free one */
  1400.         mlist[i].name = c;
  1401.         mlist[i].pos = *Curschar;
  1402.         return TRUE;
  1403.     }
  1404.     }
  1405.     return FALSE;
  1406. }
  1407.  
  1408. /*
  1409.  * setpcmark() - set the previous context mark to the current position 
  1410.  */
  1411. void
  1412. setpcmark()
  1413. {
  1414.     pcmark.pos = *Curschar;
  1415.     pcvalid = TRUE;
  1416. }
  1417.  
  1418. /*
  1419.  * getmark(c) - find mark for char 'c' 
  1420.  *
  1421.  * Return pointer to LPtr or NULL if no such mark. 
  1422.  */
  1423. LPtr           *
  1424. getmark(c)
  1425.     char            c;
  1426. {
  1427.     int             i;
  1428.  
  1429.     if (c == '\'' || c == '`')    /* previous context mark */
  1430.     return pcvalid ? &(pcmark.pos) : (LPtr *) NULL;
  1431.  
  1432.     for (i = 0; i < NMARKS; i++) {
  1433.     if (mlist[i].name == c)
  1434.         return &(mlist[i].pos);
  1435.     }
  1436.     return (LPtr *) NULL;
  1437. }
  1438.  
  1439. /*
  1440.  * clrall() - clear all marks 
  1441.  *
  1442.  * Used mainly when trashing the entire buffer during ":e" type commands 
  1443.  */
  1444. void
  1445. clrall()
  1446. {
  1447.     int             i;
  1448.  
  1449.     for (i = 0; i < NMARKS; i++)
  1450.     mlist[i].name = NUL;
  1451.     pcvalid = FALSE;
  1452. }
  1453.  
  1454. /*
  1455.  * clrmark(line) - clear any marks for 'line' 
  1456.  *
  1457.  * Used any time a line is deleted so we don't have marks pointing to
  1458.  * non-existent lines. 
  1459.  */
  1460. void
  1461. clrmark(line)
  1462.     LINE           *line;
  1463. {
  1464.     int             i;
  1465.  
  1466.     for (i = 0; i < NMARKS; i++) {
  1467.     if (mlist[i].pos.linep == line)
  1468.         mlist[i].name = NUL;
  1469.     }
  1470.     if (pcvalid && (pcmark.pos.linep == line))
  1471.     pcvalid = FALSE;
  1472. }
  1473. SHAR_EOF
  1474. cat << \SHAR_EOF > mk.c
  1475. /*
  1476.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  1477.  *
  1478.  * Code Contributions By : Tim Thompson           twitch!tjt
  1479.  *                         Tony Andrews           onecom!wldrdg!tony 
  1480.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1481.  */
  1482.  
  1483. #include "stevie.h"
  1484.  
  1485. char           *
  1486. mkline(n)
  1487.     int             n;
  1488. {
  1489.     static char     lbuf[9];
  1490.     int             i = 6;
  1491.  
  1492.     strcpy(lbuf, "        ");
  1493.  
  1494.     lbuf[i--] = (char) ((n % 10) + '0');
  1495.     n /= 10;
  1496.     if (n != 0) {
  1497.     lbuf[i--] = (char) ((n % 10) + '0');
  1498.     n /= 10;
  1499.     }
  1500.     if (n != 0) {
  1501.     lbuf[i--] = (char) ((n % 10) + '0');
  1502.     n /= 10;
  1503.     }
  1504.     if (n != 0) {
  1505.     lbuf[i--] = (char) ((n % 10) + '0');
  1506.     n /= 10;
  1507.     }
  1508.     if (n != 0) {
  1509.     lbuf[i--] = (char) ((n % 10) + '0');
  1510.     n /= 10;
  1511.     }
  1512.     return lbuf;
  1513. }
  1514.  
  1515. char           *
  1516. mkstr(c)
  1517.     char            c;
  1518. {
  1519.     static char     s[2];
  1520.  
  1521.     s[0] = c;
  1522.     s[1] = NUL;
  1523.  
  1524.     return s;
  1525. }
  1526. SHAR_EOF
  1527. cat << \SHAR_EOF > os2.h
  1528. /*
  1529.  * OS2 Machine-dependent routines. 
  1530.  */
  1531.  
  1532. int  inchar();
  1533. void outchar();
  1534. void outstr(), beep();
  1535. void windinit(), windexit(), windgoto();
  1536. void delay();
  1537. void sleep();
  1538. SHAR_EOF
  1539. cat << \SHAR_EOF > param.c
  1540. /*
  1541.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  1542.  *
  1543.  * Code Contributions By : Tim Thompson           twitch!tjt
  1544.  *                         Tony Andrews           onecom!wldrdg!tony 
  1545.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1546.  */
  1547.  
  1548. /*
  1549.  * Code to handle user-settable parameters. This is all pretty much table-
  1550.  * driven. To add a new parameter, put it in the params array, and add a
  1551.  * macro for it in param.h. If it's a numeric parameter, add any necessary
  1552.  * bounds checks to doset(). String parameters aren't currently supported. 
  1553.  */
  1554.  
  1555. #include "stevie.h"
  1556.  
  1557. struct param    params[] = {
  1558.  
  1559.                 {"tabstop", "ts", 8, P_NUM},
  1560.                 {"scroll", "scroll", 12, P_NUM},
  1561.                 {"report", "report", 5, P_NUM},
  1562.                 {"lines", "lines", 25, P_NUM},
  1563.  
  1564.                 {"vbell", "vb", TRUE, P_BOOL},
  1565.                 {"showmatch", "sm", FALSE, P_BOOL},
  1566.                 {"wrapscan", "ws", TRUE, P_BOOL},
  1567.                 {"errorbells", "eb", FALSE, P_BOOL},
  1568.                 {"showmode", "mo", FALSE, P_BOOL},
  1569.                 {"backup", "bk", FALSE, P_BOOL},
  1570.                 {"return", "cr", TRUE, P_BOOL},
  1571.                 {"list", "list", FALSE, P_BOOL},
  1572.                 {"ignorecase", "ic", FALSE, P_BOOL},
  1573.                 {"autoindent", "ai", FALSE, P_BOOL},
  1574.                 {"number", "nu", FALSE, P_BOOL},
  1575.                 {"", "", 0, 0}    /* end marker */
  1576. };
  1577.  
  1578. static void     showparms();
  1579.  
  1580. void
  1581. doset(arg, inter)
  1582.     char           *arg;    /* parameter string */
  1583.     bool_t          inter;    /* TRUE if called interactively */
  1584. {
  1585.     int             i;
  1586.     char           *s;
  1587.     bool_t          did_lines = FALSE;
  1588.  
  1589.     bool_t          state = TRUE;    /* new state of boolean parms. */
  1590.  
  1591.     if (arg == NULL) {
  1592.     showparms(FALSE);
  1593.     return;
  1594.     }
  1595.     if (strncmp(arg, "all", 3) == 0) {
  1596.     showparms(TRUE);
  1597.     return;
  1598.     }
  1599.     if (strncmp(arg, "no", 2) == 0) {
  1600.     state = FALSE;
  1601.     arg += 2;
  1602.     }
  1603.     for (i = 0; params[i].fullname[0] != NUL; i++) {
  1604.     s = params[i].fullname;
  1605.     if (strncmp(arg, s, strlen(s)) == 0)    /* matched full name */
  1606.         break;
  1607.     s = params[i].shortname;
  1608.     if (strncmp(arg, s, strlen(s)) == 0)    /* matched short name */
  1609.         break;
  1610.     }
  1611.  
  1612.     if (params[i].fullname[0] != NUL) {    /* found a match */
  1613.     if (params[i].flags & P_NUM) {
  1614.         did_lines = (i == P_LI);
  1615.         if (inter && (arg[strlen(s)] != '=' || state == FALSE))
  1616.         emsg("Invalid set of numeric parameter");
  1617.         else {
  1618.         params[i].value = atoi(arg + strlen(s) + 1);
  1619.         params[i].flags |= P_CHANGED;
  1620.         }
  1621.     } else {        /* boolean */
  1622.         if (inter && (arg[strlen(s)] == '='))
  1623.         emsg("Invalid set of boolean parameter");
  1624.         else {
  1625.         params[i].value = state;
  1626.         params[i].flags |= P_CHANGED;
  1627.         }
  1628.     }
  1629.     } else {
  1630.     if (inter)
  1631.         emsg("Unrecognized 'set' option");
  1632.     }
  1633.  
  1634.     /*
  1635.      * Update the screen in case we changed something like "tabstop" or
  1636.      * "list" that will change its appearance. 
  1637.      */
  1638.     if (inter)
  1639.     updateNextscreen(NOT_VALID);
  1640.  
  1641.     if (did_lines) {
  1642.     Rows = P(P_LI);
  1643.     screenalloc();        /* allocate new screen buffers */
  1644.     screenclear();
  1645.     updateNextscreen(NOT_VALID);
  1646.     }
  1647.     /*
  1648.      * Check the bounds for numeric parameters here 
  1649.      */
  1650.     if (P(P_TS) <= 0 || P(P_TS) > 32) {
  1651.     if (inter)
  1652.         emsg("Invalid tab size specified");
  1653.     P(P_TS) = 8;
  1654.     return;
  1655.     }
  1656.     if (P(P_SS) <= 0 || P(P_SS) > Rows) {
  1657.     if (inter)
  1658.         emsg("Invalid scroll size specified");
  1659.     P(P_SS) = 12;
  1660.     return;
  1661.     }
  1662.     /*
  1663.      * Check for another argument, and call doset() recursively, if found. If
  1664.      * any argument results in an error, no further parameters are processed. 
  1665.      */
  1666.     while (*arg != ' ' && *arg != '\t') {    /* skip to next white space */
  1667.     if (*arg == NUL)
  1668.         return;        /* end of parameter list */
  1669.     arg++;
  1670.     }
  1671.     while (*arg == ' ' || *arg == '\t')    /* skip to next non-white */
  1672.     arg++;
  1673.  
  1674.     if (*arg)
  1675.     doset(arg, TRUE);    /* recurse on next parameter, if present */
  1676. }
  1677.  
  1678. static void
  1679. showparms(all)
  1680.     bool_t          all;    /* show ALL parameters */
  1681. {
  1682.     struct param   *p;
  1683.     char            buf[64];
  1684.  
  1685.     gotocmdline(YES, NUL);
  1686.     outstr("Parameters:\r\n");
  1687.  
  1688.     for (p = ¶ms[0]; p->fullname[0] != NUL; p++) {
  1689.     if (!all && ((p->flags & P_CHANGED) == 0))
  1690.         continue;
  1691.     if (p->flags & P_BOOL)
  1692.         sprintf(buf, "\t%s%s\r\n",
  1693.             (p->value ? "" : "no"), p->fullname);
  1694.     else
  1695.         sprintf(buf, "\t%s=%d\r\n", p->fullname, p->value);
  1696.  
  1697.     outstr(buf);
  1698.     }
  1699.     wait_return();
  1700. }
  1701. SHAR_EOF
  1702. cat << \SHAR_EOF > param.h
  1703. /*
  1704.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  1705.  *
  1706.  * Code Contributions By : Tim Thompson           twitch!tjt
  1707.  *                         Tony Andrews           onecom!wldrdg!tony 
  1708.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  1709.  */
  1710.  
  1711. /*
  1712.  * Settable parameters 
  1713.  */
  1714.  
  1715. struct param {
  1716.     char           *fullname;    /* full parameter name */
  1717.     char           *shortname;    /* permissible abbreviation */
  1718.     int             value;    /* parameter value */
  1719.     int             flags;
  1720. };
  1721.  
  1722. extern struct param params[];
  1723.  
  1724. /*
  1725.  * Flags 
  1726.  */
  1727. #define    P_BOOL        0x01    /* the parameter is boolean */
  1728. #define    P_NUM        0x02    /* the parameter is numeric */
  1729. #define    P_CHANGED    0x04    /* the parameter has been changed */
  1730.  
  1731. /*
  1732.  * The following are the indices in the params array for each parameter 
  1733.  */
  1734.  
  1735. /*
  1736.  * Numeric parameters 
  1737.  */
  1738. #define    P_TS        0    /* tab size */
  1739. #define    P_SS        1    /* scroll size */
  1740. #define    P_RP        2    /* report */
  1741. #define    P_LI        3    /* lines */
  1742.  
  1743. /*
  1744.  * Boolean parameters 
  1745.  */
  1746. #define    P_VB        4    /* visual bell */
  1747. #define    P_SM        5    /* showmatch */
  1748. #define    P_WS        6    /* wrap scan */
  1749. #define    P_EB        7    /* error bells */
  1750. #define    P_MO        8    /* show mode */
  1751. #define    P_BK        9    /* make backups when writing out files */
  1752. #define    P_CR        10    /* use cr-lf to terminate lines on writes */
  1753. #define    P_LS        11    /* show tabs and newlines graphically */
  1754. #define    P_IC        12    /* ignore case in searches */
  1755. #define    P_AI        13    /* auto-indent */
  1756. #define    P_NU        14    /* number lines on the screen */
  1757.  
  1758. /*
  1759.  * Macro to get the value of a parameter 
  1760.  */
  1761. #define    P(n)    (params[n].value)
  1762. SHAR_EOF
  1763. cat << \SHAR_EOF > porting.doc
  1764.  
  1765.          Release Notes for STEVIE - Version 3.31B
  1766.  
  1767.                    Porting
  1768.  
  1769.              Tony Andrews -  March 6, 1988
  1770.             G. R. Walter -  January 6, 1988
  1771.  
  1772.  
  1773.     Porting the editor is a relatively simple task. Most of the
  1774. code is pretty machine-independent. For each environment, there is
  1775. a file of routines that perform various low-level operations that
  1776. tend to vary a lot from one machine to another. Another file contains
  1777. the escape sequences to be used for each machine.
  1778.  
  1779.     The machine-dependent files currently used are:
  1780.  
  1781. tos.c:     Atari ST - ifdef for either Megamax or Alcyon
  1782. tos.h
  1783.  
  1784. unix.c:     UNIX System V
  1785. unix.h
  1786.  
  1787. os2.c:     Microsoft OS/2
  1788. os2.h
  1789.  
  1790. dos.c:   MS DOS
  1791. dos.h
  1792.  
  1793. amiga.c: Amiga
  1794. amiga.h
  1795.  
  1796. bsd.c:   BSD 4.3 UNIX
  1797. bsd.h
  1798.  
  1799.     Each of these files are around 150 lines long and deal with
  1800. low-level issues like character I/O to the terminal, terminal
  1801. initialization, cursor addressing, and so on. There are different
  1802. tradeoffs to be made depending on the environment. For example, the
  1803. UNIX version buffers terminal output because of the relatively high
  1804. overhead of system calls. A quick look at the files will make it clear
  1805. what needs to be done in a new environment.
  1806.  
  1807.     Terminal escape sequences are in the file "term.h". These are
  1808. defined statically, for the time being. There is some discussion in
  1809. term.h regarding which sequences are optional and which are not. The
  1810. editor is somewhat flexible in dealing with a lack of terminal
  1811. capabilities.
  1812.  
  1813.     The character set is in the file "charset.c".
  1814.  
  1815.     Because not all C compilers support command line macro definitions,
  1816. the #define's for system-specific macros are placed in the file "env.h".
  1817. If you port to a new system, add another line there to define the macro you
  1818. choose for your port.
  1819.  
  1820.     The basic process for doing a new port is:
  1821.  
  1822.     1. Come up with a macro name to use when ifdef'ing your system-
  1823.        specific changes. Add a line to 'env.h' to define
  1824.        the macro name you've chosen.
  1825.  
  1826.     2. Look at amiga.c, bsd.c, unix.c, tos.c, dos.c and os2.c and copy the
  1827.        one that comes closest to working on your system. Then modify your
  1828.        new file as needed.
  1829.  
  1830.     3. Look at term.h and edit the file appropriately adding a new
  1831.        set of escape sequence definitions for your system.
  1832.  
  1833.     4. Compiling and debug the editor.
  1834. SHAR_EOF
  1835. cat << \SHAR_EOF > raw.c
  1836. /*
  1837.  * raw.c 
  1838.  *
  1839.  * This is a routine for setting a given stream to raw or cooked mode on the
  1840.  * Amiga . This is useful when you are using Lattice C to produce programs
  1841.  * that want to read single characters with the "getch()" or "fgetc" call. 
  1842.  *
  1843.  * Written : 18-Jun-87 By Chuck McManis.
  1844.  */
  1845.  
  1846. #include <proto/exec.h>
  1847. #include <proto/dos.h>
  1848. #include <stdio.h>
  1849. #include <ios1.h>
  1850. #include <error.h>
  1851.  
  1852. extern int      errno;        /* The error variable */
  1853.  
  1854. /*
  1855.  * Function raw() - Convert the specified file pointer to 'raw' mode. This
  1856.  * only works on TTY's and essentially keeps DOS from translating keys for
  1857.  * you, also (BIG WIN) it means getch() will return immediately rather than
  1858.  * wait for a return. You lose editing features though. 
  1859.  */
  1860. long
  1861. raw(fp)
  1862.     FILE           *fp;
  1863.  
  1864. {
  1865.     struct MsgPort *mp;        /* The File Handle message port */
  1866.     struct FileHandle *afh;
  1867.     struct UFB     *ufb;
  1868.     long            Arg[1], res;
  1869.  
  1870.     ufb = (struct UFB *) chkufb(fileno(fp));    /* Step one, get the file
  1871.                          * handle */
  1872.     afh = (struct FileHandle *) (ufb->ufbfh);
  1873.  
  1874.     if (!IsInteractive(afh)) {    /* Step two, check to see if it's a console */
  1875.     errno = ENOTTY;
  1876.     return (-1);
  1877.     }
  1878.     /* Step three, get it's message port. */
  1879.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  1880.     Arg[0] = -1L;
  1881.     res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);    /* Put it in RAW: mode */
  1882.     if (res == 0) {
  1883.     errno = ENXIO;
  1884.     return (-1);
  1885.     }
  1886.     return (0);
  1887. }
  1888.  
  1889. /*
  1890.  * Function - cooked() this function returns the designate file pointer to
  1891.  * it's normal, wait for a <CR> mode. This is exactly like raw() except that
  1892.  * it sends a 0 to the console to make it back into a CON: from a RAW: 
  1893.  */
  1894.  
  1895. long
  1896. cooked(fp)
  1897.     FILE           *fp;
  1898.  
  1899. {
  1900.     struct MsgPort *mp;        /* The File Handle message port */
  1901.     struct FileHandle *afh;
  1902.     struct UFB     *ufb;
  1903.     long            Arg[1], res;
  1904.  
  1905.     ufb = (struct UFB *) chkufb(fileno(fp));
  1906.     afh = (struct FileHandle *) (ufb->ufbfh);
  1907.     if (!IsInteractive(afh)) {
  1908.     errno = ENOTTY;
  1909.     return (-1);
  1910.     }
  1911.     mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
  1912.     Arg[0] = 0;
  1913.     res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
  1914.     if (res == 0) {
  1915.     errno = ENXIO;
  1916.     return (-1);
  1917.     }
  1918.     return (0);
  1919. }
  1920. SHAR_EOF
  1921. cat << \SHAR_EOF > regexp.h
  1922. /*
  1923.  * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  1924.  *
  1925.  * This is NOT the original regular expression code as written by
  1926.  * Henry Spencer. This code has been modified specifically for use
  1927.  * with the STEVIE editor, and should not be used apart from compiling
  1928.  * STEVIE. If you want a good regular expression library, get the
  1929.  * original code. The copyright notice that follows is from the
  1930.  * original.
  1931.  *
  1932.  * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  1933.  *
  1934.  * Definitions etc. for regexp(3) routines.
  1935.  *
  1936.  * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
  1937.  * not the System V one.
  1938.  */
  1939. #define NSUBEXP  10
  1940. typedef struct regexp {
  1941.     char           *startp[NSUBEXP];
  1942.     char           *endp[NSUBEXP];
  1943.     char            regstart;    /* Internal use only. */
  1944.     char            reganch;    /* Internal use only. */
  1945.     char           *regmust;    /* Internal use only. */
  1946.     int             regmlen;    /* Internal use only. */
  1947.     char            program[1];    /* Unwarranted chumminess with compiler. */
  1948. }               regexp;
  1949.  
  1950. extern regexp  *regcomp();
  1951. extern int      regexec();
  1952. extern void     regsub();
  1953. extern void     regerror();
  1954.  
  1955. #ifndef    ORIGINAL
  1956. extern int      reg_ic;        /* set non-zero to ignore case in searches */
  1957. #endif
  1958. SHAR_EOF
  1959. cat << \SHAR_EOF > regmagic.h
  1960. /*
  1961.  * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  1962.  *
  1963.  * This is NOT the original regular expression code as written by
  1964.  * Henry Spencer. This code has been modified specifically for use
  1965.  * with the STEVIE editor, and should not be used apart from compiling
  1966.  * STEVIE. If you want a good regular expression library, get the
  1967.  * original code. The copyright notice that follows is from the
  1968.  * original.
  1969.  *
  1970.  * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  1971.  *
  1972.  * The first byte of the regexp internal "program" is actually this magic
  1973.  * number; the start node begins in the second byte.
  1974.  */
  1975. #define    MAGIC    0234
  1976. SHAR_EOF
  1977. cat << \SHAR_EOF > regsub.c
  1978. /*
  1979.  * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  1980.  *
  1981.  * This is NOT the original regular expression code as written by
  1982.  * Henry Spencer. This code has been modified specifically for use
  1983.  * with the STEVIE editor, and should not be used apart from compiling
  1984.  * STEVIE. If you want a good regular expression library, get the
  1985.  * original code. The copyright notice that follows is from the
  1986.  * original.
  1987.  *
  1988.  * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
  1989.  *
  1990.  * regsub
  1991.  *
  1992.  *    Copyright (c) 1986 by University of Toronto.
  1993.  *    Written by Henry Spencer.  Not derived from licensed software.
  1994.  *
  1995.  *    Permission is granted to anyone to use this software for any
  1996.  *    purpose on any computer system, and to redistribute it freely,
  1997.  *    subject to the following restrictions:
  1998.  *
  1999.  *    1. The author is not responsible for the consequences of use of
  2000.  *        this software, no matter how awful, even if they arise
  2001.  *        from defects in it.
  2002.  *
  2003.  *    2. The origin of this software must not be misrepresented, either
  2004.  *        by explicit claim or by omission.
  2005.  *
  2006.  *    3. Altered versions must be plainly marked as such, and must not
  2007.  *        be misrepresented as being the original software.
  2008.  *
  2009.  * $Log:    regsub.c,v $
  2010.  * Revision 1.2  88/04/28  08:11:25  tony
  2011.  * First modification of the regexp library. Added an external variable
  2012.  * 'reg_ic' which can be set to indicate that case should be ignored.
  2013.  * Added a new parameter to regexec() to indicate that the given string
  2014.  * comes from the beginning of a line and is thus eligible to match
  2015.  * 'beginning-of-line'.
  2016.  * 
  2017.  */
  2018.  
  2019. #include "env.h"
  2020.  
  2021. #ifdef    MEGAMAX
  2022. overlay "regexp"
  2023. #endif
  2024.  
  2025. #include <stdio.h>
  2026. #include "regexp.h"
  2027. #include "regmagic.h"
  2028.  
  2029. #ifndef CHARBITS
  2030. #define    UCHARAT(p)    ((int)*(unsigned char *)(p))
  2031. #else
  2032. #define    UCHARAT(p)    ((int)*(p)&CHARBITS)
  2033. #endif
  2034.  
  2035. /*
  2036.  - regsub - perform substitutions after a regexp match
  2037.  */
  2038. void
  2039. regsub(prog, source, dest)
  2040.     regexp         *prog;
  2041.     char           *source;
  2042.     char           *dest;
  2043. {
  2044.     register char  *src;
  2045.     register char  *dst;
  2046.     register char   c;
  2047.     register int    no;
  2048.     register int    len;
  2049.     extern char    *strncpy();
  2050.  
  2051.     if (prog == NULL || source == NULL || dest == NULL) {
  2052.     regerror("NULL parm to regsub");
  2053.     return;
  2054.     }
  2055.     if (UCHARAT(prog->program) != MAGIC) {
  2056.     regerror("damaged regexp fed to regsub");
  2057.     return;
  2058.     }
  2059.     src = source;
  2060.     dst = dest;
  2061.     while ((c = *src++) != '\0') {
  2062.     if (c == '&')
  2063.         no = 0;
  2064.     else if (c == '\\' && '0' <= *src && *src <= '9')
  2065.         no = *src++ - '0';
  2066.     else
  2067.         no = -1;
  2068.     if (no < 0) {        /* Ordinary character. */
  2069.         if (c == '\\' && (*src == '\\' || *src == '&'))
  2070.         c = *src++;
  2071.         *dst++ = c;
  2072.     } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
  2073.         len = prog->endp[no] - prog->startp[no];
  2074.         (void) strncpy(dst, prog->startp[no], len);
  2075.         dst += len;
  2076.         if (len != 0 && *(dst - 1) == '\0') {    /* strncpy hit NUL. */
  2077.         regerror("damaged match string");
  2078.         return;
  2079.         }
  2080.     }
  2081.     }
  2082.     *dst++ = '\0';
  2083. }
  2084. SHAR_EOF
  2085. cat << \SHAR_EOF > sendpacket.c
  2086. /*
  2087.  * Sendpacket.c 
  2088.  *
  2089.  * An invaluable addition to your Amiga.lib file. This code sends a packet the
  2090.  * given message port. This makes working around DOS lots easier. 
  2091.  *
  2092.  * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
  2093.  * however that you may wish to add it to Amiga.Lib, to do so, compile it and
  2094.  * say 'oml lib:amiga.lib -r sendpacket.o' 
  2095.  */
  2096.  
  2097. #include <proto/exec.h>
  2098. /* #include <exec/ports.h> */
  2099. #include <exec/memory.h>
  2100. #include <proto/dos.h>
  2101.  
  2102. /*
  2103.  * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
  2104.  * Finkel. This function will send a packet of the given type to the Message
  2105.  * Port supplied. 
  2106.  */
  2107.  
  2108. long
  2109. SendPacket(pid, action, args, nargs)
  2110.     struct MsgPort *pid;    /* process indentifier ... (handlers message
  2111.                  * port ) */
  2112.     long            action,    /* packet type ... (what you want handler to
  2113.                  * do )   */
  2114.                     args[],    /* a pointer to a argument list */
  2115.                     nargs;    /* number of arguments in list  */
  2116. {
  2117.     struct MsgPort *replyport;
  2118.     struct StandardPacket *packet;
  2119.  
  2120.     long            count, *pargs, res1;
  2121.  
  2122.     replyport = (struct MsgPort *) CreatePort(NULL, 0);
  2123.     if (!replyport)
  2124.     return (0);
  2125.  
  2126.     /* Allocate space for a packet, make it public and clear it */
  2127.     packet = (struct StandardPacket *)
  2128.     AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
  2129.     if (!packet) {
  2130.     DeletePort(replyport);
  2131.     return (0);
  2132.     }
  2133.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  2134.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  2135.     packet->sp_Pkt.dp_Port = replyport;
  2136.     packet->sp_Pkt.dp_Type = action;
  2137.  
  2138.     /* copy the args into the packet */
  2139.     pargs = &(packet->sp_Pkt.dp_Arg1);    /* address of first argument */
  2140.     for (count = 0; count < nargs; count++)
  2141.     pargs[count] = args[count];
  2142.  
  2143.     PutMsg(pid, packet);    /* send packet */
  2144.  
  2145.     WaitPort(replyport);
  2146.     GetMsg(replyport);
  2147.  
  2148.     res1 = packet->sp_Pkt.dp_Res1;
  2149.  
  2150.     FreeMem(packet, (long) sizeof(struct StandardPacket));
  2151.     DeletePort(replyport);
  2152.  
  2153.     return (res1);
  2154. }
  2155. SHAR_EOF
  2156. cat << \SHAR_EOF > source.doc
  2157.  
  2158.          Release Notes for STEVIE - Version 3.10a
  2159.  
  2160.                   Source Notes
  2161.  
  2162.               Tony Andrews - March 6, 1988
  2163.  
  2164. Overview
  2165. --------
  2166.  
  2167.     This file provides a brief description of the source code for
  2168. Stevie. The data structures are described later as well. For information
  2169. specific to porting the editor, see the file 'porting.doc'. This document
  2170. is more relevant to people who want to hack on the editor apart from doing
  2171. a simple port.
  2172.  
  2173.     Most of this document was written some time ago so a lot of the
  2174. discussion centers on problems related to the Atari ST environment and
  2175. compilers. Most of this can be ignored for other systems.
  2176.  
  2177. Things You Need - ATARI
  2178. -----------------------
  2179.  
  2180.     Stevie has been compiled with both the Alcyon (4.14A) and the
  2181. Megamax C compilers. For the posted binary, Megamax was used because
  2182. it's less buggy and provides a reasonable malloc(). Ports to other
  2183. compilers should be pretty simple. The current ifdef's for ALCYON and
  2184. MEGAMAX should point to the potential trouble areas. (See 'porting.doc'
  2185. for more information.)
  2186.  
  2187.     The search code depends on Henry Spencer's regular expression
  2188. code. I used a version I got from the net recently (as part of a 'grep'
  2189. posting) and had absolutely no trouble compiling it on the ST. Thanks,
  2190. Henry!
  2191.  
  2192.     The file 'getenv.c' contains a getenv routine that may or may
  2193. not be needed with your compiler. My version works with Alcyon and
  2194. Megamax, under either the Beckemeyer or Gulam shells.
  2195.  
  2196.     Lastly, you need a decent malloc. Lots of stuff in stevie is
  2197. allocated dynamically. The malloc with Alcyon is problematic because
  2198. it allocates from the heap between the end of data and the top of stack.
  2199. If you make the stack big enough to edit large files, you wind up
  2200. wasting space when working with small files. Mallocs that get their memory
  2201. from GEMDOS (in fairly large chunks) are much better.
  2202.  
  2203. Things You Need - AMIGA
  2204. -----------------------
  2205.  
  2206.     Lattice C version 5.0 or later.
  2207.  
  2208. Data Structures
  2209. ---------------
  2210.  
  2211.     A brief discussion of the evolution of the data structures will
  2212. do much to clarify the code, and explain some of the strangeness you may
  2213. see.
  2214.  
  2215.     In the original version, the file was maintained in memory as a
  2216. simple contiguous buffer. References to positions in the file were simply
  2217. character pointers. Due to the obvious performance problems inherent in
  2218. this approach, the following changes were made.
  2219.  
  2220.     The file is now represented by a doubly linked list of 'line'
  2221. structures defined as follows:
  2222.  
  2223. struct    line {
  2224.     struct    line   *next;    /* next line */
  2225.     struct    line   *prev;    /* previous line */
  2226.     char           *s;    /* text for this line */
  2227.     int            size;    /* actual size of space at 's' */
  2228.     unsigned long   num;    /* line "number" */
  2229. };
  2230.  
  2231. The members of the line structure are described more completely here:
  2232.  
  2233. prev    - pointer to the structure for the prior line, or NULL for the
  2234.       first line of the file
  2235.  
  2236. next    - like 'prev' but points to the next line
  2237.  
  2238. s    - points to the contents of the line (null terminated)
  2239.  
  2240. size    - contains the size of the chunk of space pointed to by s. This
  2241.       is used so we know when we can add text to a line without getting
  2242.       more space. When we DO need more space, we always get a little
  2243.       extra so we don't make so many calls to malloc.
  2244.  
  2245. num    - This is a pseudo line number that makes it easy to compare
  2246.       positions within the file. Otherwise, we'd have to traverse
  2247.       all the links to tell which line came first.
  2248.  
  2249.     Since character pointers served to mark file positions in the
  2250. original, a similar data object was needed for the new data structures.
  2251. This purpose is served by the 'lptr' structure which is defined as:
  2252.  
  2253. struct    lptr {
  2254.     struct    line   *linep;    /* line we're referencing */
  2255.     int             index;    /* position within that line */
  2256. };
  2257.  
  2258. The member 'linep' points to the 'line' structure for the line containing
  2259. the location of interest. The integer 'index' is the offset into the line
  2260. data (member 's') of the character to be referenced.
  2261.  
  2262. The following typedef's are more commonly used:
  2263.  
  2264. typedef    struct line    LINE;
  2265. typedef    struct lptr    LPtr;
  2266.  
  2267. Many operations that were trivial with character pointers had to be
  2268. implemented by functions or macros to manipulate LPtr's. Most of these are in
  2269. the files 'ptrfunc.c' and 'macros.h'. There you'll find functions to increment,
  2270. decrement, and compare LPtr's.
  2271. SHAR_EOF
  2272. cat << \SHAR_EOF > tos.h
  2273. /*
  2274.  * Atari Machine-dependent routines. 
  2275.  */
  2276.  
  2277. int  inchar();
  2278. void outchar();
  2279. void outstr(), beep();
  2280. void remove(), rename();
  2281. void windinit(), windexit(), windgoto();
  2282. void delay();
  2283. void sleep();
  2284. SHAR_EOF
  2285. cat << \SHAR_EOF > unix.c
  2286. /*
  2287.  * System-dependent routines for UNIX System V Release 3. 
  2288.  */
  2289.  
  2290. #include "stevie.h"
  2291. /* #include <termio.h> /* System V */
  2292. #include <curses.h>        /* BSD */
  2293.  
  2294. /*
  2295.  * inchar() - get a character from the keyboard 
  2296.  */
  2297. int
  2298. inchar()
  2299. {
  2300.     char            c;
  2301.  
  2302.     flushbuf();            /* flush any pending output */
  2303.  
  2304.     while (read(0, &c, 1) != 1);
  2305.  
  2306.     return (int) c;
  2307. }
  2308.  
  2309. #define    BSIZE    2048
  2310. static char     outbuf[BSIZE];
  2311. static int      bpos = 0;
  2312.  
  2313. flushbuf()
  2314. {
  2315.     if (bpos != 0)
  2316.     write(1, outbuf, bpos);
  2317.     bpos = 0;
  2318. }
  2319.  
  2320. /*
  2321.  * Macro to output a character. Used within this file for speed. 
  2322.  */
  2323. #define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  2324.  
  2325. /*
  2326.  * Function version for use outside this file. 
  2327.  */
  2328. void
  2329. outchar(c)
  2330.     char            c;
  2331. {
  2332.     outbuf[bpos++] = c;
  2333.     if (bpos >= BSIZE)
  2334.     flushbuf();
  2335. }
  2336.  
  2337. void
  2338. outstr(s)
  2339.     char           *s;
  2340. {
  2341.     while (*s) {
  2342.     outone(*s++);
  2343.     }
  2344. }
  2345.  
  2346. void
  2347. beep()
  2348. {
  2349.     if (RedrawingDisabled)
  2350.     return;
  2351.  
  2352.     outone('\007');
  2353. }
  2354.  
  2355. /*
  2356.  * remove(file) - remove a file 
  2357.  */
  2358. void
  2359. remove(file)
  2360.     char           *file;
  2361. {
  2362.     unlink(file);
  2363. }
  2364.  
  2365. /*
  2366.  * rename(of, nf) - rename existing file 'of' to 'nf' 
  2367.  */
  2368. void
  2369. rename(of, nf)
  2370.     char           *of, *nf;
  2371. {
  2372.     unlink(nf);
  2373.     link(of, nf);
  2374.     unlink(of);
  2375. }
  2376.  
  2377. void
  2378. delay()
  2379. {
  2380.     /* not implemented */
  2381. }
  2382.  
  2383. static struct termio ostate;
  2384.  
  2385. void
  2386. windinit()
  2387. {
  2388.     char           *getenv();
  2389.     char           *term;
  2390.     struct termio   nstate;
  2391.  
  2392.     if ((term = getenv("TERM")) == NULL || strcmp(term, "vt100") != 0) {
  2393.     fprintf(stderr, "Invalid terminal type '%s'\n", term);
  2394.     exit(1);
  2395.     }
  2396.     Columns = 80;
  2397.     P(P_LI) = Rows = 24;
  2398.  
  2399.     /*
  2400.      * Go into cbreak mode 
  2401.      */
  2402.     ioctl(0, TCGETA, &ostate);
  2403.     nstate = ostate;
  2404.     nstate.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL);
  2405.     nstate.c_cc[VMIN] = 1;
  2406.     nstate.c_cc[VTIME] = 0;
  2407.     ioctl(0, TCSETAW, &nstate);
  2408. }
  2409.  
  2410. void
  2411. windexit(r)
  2412.     int             r;
  2413. {
  2414.     /*
  2415.      * Restore terminal modes 
  2416.      */
  2417.     ioctl(0, TCSETAW, &ostate);
  2418.  
  2419.     exit(r);
  2420. }
  2421.  
  2422. #define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  2423.  
  2424. void
  2425. windgoto(r, c)
  2426.     int             r, c;
  2427. {
  2428.     r += 1;
  2429.     c += 1;
  2430.  
  2431.     /*
  2432.      * Check for overflow once, to save time. 
  2433.      */
  2434.     if (bpos + 8 >= BSIZE)
  2435.     flushbuf();
  2436.  
  2437.     outbuf[bpos++] = '\033';
  2438.     outbuf[bpos++] = '[';
  2439.     if (r >= 10)
  2440.     outbuf[bpos++] = r / 10 + '0';
  2441.     outbuf[bpos++] = r % 10 + '0';
  2442.     outbuf[bpos++] = ';';
  2443.     if (c >= 10)
  2444.     outbuf[bpos++] = c / 10 + '0';
  2445.     outbuf[bpos++] = c % 10 + '0';
  2446.     outbuf[bpos++] = 'H';
  2447. }
  2448.  
  2449. FILE           *
  2450. fopenb(fname, mode)
  2451.     char           *fname;
  2452.     char           *mode;
  2453. {
  2454.     return fopen(fname, mode);
  2455. }
  2456. SHAR_EOF
  2457. cat << \SHAR_EOF > unix.h
  2458. /*
  2459.  * Unix Machine-dependent routines. 
  2460.  */
  2461.  
  2462. int  inchar();
  2463. void outchar();
  2464. void outstr(), beep();
  2465. void remove(), rename();
  2466. void windinit(), windexit(), windgoto();
  2467. void delay();
  2468. SHAR_EOF
  2469. cat << \SHAR_EOF > updateNs.c
  2470. /*
  2471.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  2472.  *
  2473.  * Code Contributions By : Tim Thompson           twitch!tjt
  2474.  *                         Tony Andrews           onecom!wldrdg!tony 
  2475.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2476.  */
  2477.  
  2478. #include "stevie.h"
  2479.  
  2480. /*
  2481.  * updateNextscreen() 
  2482.  *
  2483.  * Based on the current value of Topchar, transfer a screenfull of stuff from
  2484.  * Filemem to Nextscreen, and update Botchar. 
  2485.  */
  2486.  
  2487. void
  2488. updateNextscreen(type)
  2489.     int             type;
  2490. {
  2491.     register char  *ptr;
  2492.     register char   c;
  2493.     register int    row;
  2494.     register int    col;
  2495.     register char  *screenp;
  2496.     register char  *endscreen;
  2497.     register char  *nextrow;
  2498.     LPtr            start;
  2499.     LINE           *memp;
  2500.     LINE           *save;    /* save pos. in case line won't fit */
  2501.     char            extra[16];
  2502.     char           *p_extra;
  2503.     int             n_extra;
  2504.     bool_t          done;    /* if TRUE, we hit the end of the file */
  2505.     bool_t          didline;    /* if TRUE, we finished the last line */
  2506.     int             srow;    /* starting row of the current line */
  2507.     int             lno;    /* number of the line we're doing */
  2508.     int             coff;    /* column offset */
  2509.     int             idx;
  2510.     int             i;
  2511.     int             j;
  2512.     char            lines;
  2513.  
  2514.     if (NumLineSizes == 0)
  2515.     type = NOT_VALID;
  2516.  
  2517.     MustRedrawLine = FALSE;
  2518.     MustRedrawScreen = TRUE;
  2519.  
  2520.     idx = 0;
  2521.     row = 0;
  2522.     start.linep = Topchar->linep;
  2523.     screenp = Nextscreen;
  2524.  
  2525.     /* The number of rows shown is Rows-1. */
  2526.     /* The last line is the status/command line. */
  2527.     endscreen = Nextscreen + (Rows - 1) * Columns;
  2528.  
  2529.     if ((type == VALID) || (type == VALID_TO_CURSCHAR)) {
  2530.     j = -1;
  2531.     for (i = 0; i < NumLineSizes; i++) {
  2532.         if (LinePointers[i] == Topchar->linep) {
  2533.         j = i;
  2534.         break;
  2535.         }
  2536.         row += LineSizes[i];
  2537.     }
  2538.     if (j == -1) {
  2539.         /* Are we off the top of the screen by one line ? */
  2540.         if (Topchar->linep->next == LinePointers[0]) {
  2541.         i = plines(Topchar);
  2542.         if (i < (Rows - 1)) {
  2543.             screenp = endscreen - (i * Columns);
  2544.         
  2545.             while (screenp > Nextscreen)
  2546.                 *(--endscreen) = *(--screenp);
  2547.  
  2548.             endscreen = Nextscreen + (i * Columns);
  2549.  
  2550.             for(idx = NumLineSizes;  idx > 0;  idx--) {
  2551.             LinePointers[idx] = LinePointers[idx - 1];
  2552.             LineSizes[idx] = LineSizes[idx - 1];
  2553.             }
  2554.             LineSizes[idx] = i;
  2555.         }
  2556.         }
  2557.         row = 0;
  2558.     } else if (j == 0 && type == VALID) {
  2559.         return;
  2560.     } else {
  2561.         nextrow = Nextscreen + row * Columns;
  2562.         row = 0;
  2563.         for (;;) {
  2564.         LineSizes[idx] = LineSizes[j];
  2565.         LinePointers[idx] = LinePointers[j];
  2566.  
  2567.         if (type == VALID_TO_CURSCHAR) {
  2568.             if (LinePointers[idx]->next == Curschar->linep) {
  2569.             break;
  2570.             }
  2571.         }
  2572.         j++;
  2573.         if (j >= NumLineSizes)
  2574.             break;
  2575.  
  2576.         row += LineSizes[idx];
  2577.         idx++;
  2578.         }
  2579.         start.linep = LinePointers[idx];
  2580.  
  2581.         endscreen = nextrow + row * Columns;
  2582.         while (nextrow < endscreen)
  2583.         *screenp++ = *nextrow++;
  2584.             endscreen = Nextscreen + (Rows - 1) * Columns;
  2585.     }
  2586.     }
  2587.  
  2588.     srow = row;
  2589.     save = memp = start.linep;
  2590.  
  2591.     coff = P(P_NU) ? 8 : 0;
  2592.  
  2593.     if (P(P_NU))
  2594.     lno = cntllines(Filemem, &start);
  2595.  
  2596.     done = didline = FALSE;
  2597.     col = 0;
  2598.     lines = 1;
  2599.  
  2600.     LinePointers[idx] = memp;
  2601.  
  2602.     p_extra = NULL;
  2603.     n_extra = 0;
  2604.     if (P(P_NU)) {
  2605.     strcpy(extra, mkline(lno++));
  2606.     p_extra = extra;
  2607.     n_extra = 8;
  2608.     }
  2609.     ptr = memp->s;
  2610.  
  2611.     /*
  2612.      * We go one past the end of the screen so we can find out if the last
  2613.      * line fit on the screen or not. 
  2614.      */
  2615.     while (screenp <= endscreen) {
  2616.  
  2617.     /* Get the next character to put on the screen. */
  2618.  
  2619.     /*
  2620.      * The 'extra' array contains the extra stuff that is inserted to
  2621.      * represent special characters (tabs, and other non-printable stuff. 
  2622.      */
  2623.  
  2624.     if (n_extra > 0) {
  2625.         c = *p_extra++;
  2626.         n_extra--;
  2627.     } else {
  2628.         c = *ptr++;
  2629.         if (c < 32 || c > 127) {
  2630.             if (c == NUL) {
  2631.             srow = ++row;
  2632.             /*
  2633.              * Save this position in case the next line won't fit on the
  2634.              * screen completely. 
  2635.              */
  2636.             save = memp;
  2637.             if (memp->next != Fileend->linep) {
  2638.                 memp = memp->next;
  2639.                 ptr = memp->s;
  2640.             } else {
  2641.                 done = TRUE;
  2642.             }
  2643.             if (P(P_LS)) {
  2644.                 *screenp++ = '$';
  2645.                 if (screenp > endscreen)
  2646.                 break;
  2647.                 col++;
  2648.                 if (col >= Columns) {
  2649.                 row++;
  2650.                 lines++;
  2651.                 }
  2652.             }
  2653.  
  2654.             LineSizes[idx++] = lines;
  2655.             lines = 1;
  2656.             LinePointers[idx] = memp;
  2657.             if (P(P_NU)) {
  2658.                 strcpy(extra, mkline(lno++));
  2659.                 p_extra = extra;
  2660.                 n_extra = 8;
  2661.             }
  2662.             /* blank out the rest of this row */
  2663.             nextrow = Nextscreen + (row * Columns);
  2664.             while (screenp < nextrow)
  2665.                 *screenp++ = ' ';
  2666.  
  2667.             if (done)
  2668.                 break;
  2669.  
  2670.             if (screenp == endscreen) {
  2671.             didline = TRUE;
  2672.             break;
  2673.             } else if (screenp > endscreen) {
  2674.             idx--;
  2675.             break;
  2676.             }
  2677.  
  2678.             col = 0;
  2679.             continue;
  2680.             } else if (c == TAB) {
  2681.                 if (!P(P_LS)) {
  2682.                 strcpy(extra, "               ");
  2683.                 p_extra = extra;
  2684.                 /* tab amount depends on current column */
  2685.                 n_extra = ((P(P_TS) - 1) - (col - coff) % P(P_TS));
  2686.                 c = ' ';
  2687.             }
  2688.         } else if ((n_extra = chars[c].ch_size - 1) > 0) {
  2689.             p_extra = chars[c].ch_str;
  2690.             c = *p_extra++;
  2691.             }
  2692.         }
  2693.     }
  2694.  
  2695.     if (col >= Columns) {
  2696.         lines++;
  2697.         row++;
  2698.         col = 0;
  2699.     }
  2700.     /* store the character in Nextscreen */
  2701.     *screenp++ = c;
  2702.     col++;
  2703.     }
  2704.  
  2705.     /* Do we have to do off the top of the screen processing ? */
  2706.     if (endscreen != (Nextscreen + (Rows - 1) * Columns)) {
  2707.         endscreen = Nextscreen + (Rows - 1) * Columns;
  2708.  
  2709.     row = 0;
  2710.     for(idx = 0; idx <= NumLineSizes && row < (Rows - 1);  idx++)
  2711.         row += LineSizes[idx];
  2712.  
  2713.     if (row < (Rows - 1)) {
  2714.         screenp = Nextscreen + (row * Columns);
  2715.         done = TRUE;
  2716.     } else if (row > (Rows - 1)) {    /* Need to blank out the last line */
  2717.         idx--;
  2718.         save = LinePointers[idx];
  2719.         srow = row - LineSizes[idx];
  2720.         didline = FALSE;
  2721.     } else {
  2722.         memp = LinePointers[idx];
  2723.         screenp = Nextscreen + (row * Columns);
  2724.         didline = TRUE;
  2725.     }
  2726.     }
  2727.  
  2728.     /*
  2729.      * If we didn't hit the end of the file, and we didn't finish the last
  2730.      * line we were working on, then the line didn't fit. 
  2731.      */
  2732.     if (!done && !didline) {
  2733.     /*
  2734.      * Clear the rest of the screen and mark the unused lines. 
  2735.      */
  2736.     screenp = Nextscreen + (srow * Columns);
  2737.     while (screenp < endscreen)
  2738.         *screenp++ = ' ';
  2739.  
  2740.     for (; srow < (Rows - 1); srow++)
  2741.         Nextscreen[srow * Columns] = '@';
  2742.  
  2743.     Botchar->linep = save;
  2744.     } else {
  2745.     /* make sure the rest of the screen is blank */
  2746.     while (screenp < endscreen)
  2747.         *screenp++ = ' ';
  2748.  
  2749.     /* put '~'s on rows that aren't part of the file. */
  2750.     if (col != 0)
  2751.         row++;
  2752.     while (row < Rows) {
  2753.         Nextscreen[row * Columns] = '~';
  2754.         row++;
  2755.     }
  2756.  
  2757.     if (done)        /* we hit the end of the file */
  2758.         *Botchar = *Fileend;
  2759.     else
  2760.         Botchar->linep = memp;    /* FIX - prev? */
  2761.     }
  2762.  
  2763.     NumLineSizes = idx;
  2764. }
  2765. SHAR_EOF
  2766. cat << \SHAR_EOF > updateRs.c
  2767. /*
  2768.  * STEVIE - Simply Try this Editor for VI Enthusiasts
  2769.  *
  2770.  * Code Contributions By : Tim Thompson           twitch!tjt
  2771.  *                         Tony Andrews           onecom!wldrdg!tony 
  2772.  *                         G. R. (Fred) Walter    watmath!watcgl!grwalter 
  2773.  */
  2774.  
  2775. #include "stevie.h"
  2776.  
  2777. /*
  2778.  * updateRealscreen 
  2779.  *
  2780.  * Transfer the contents of Nextscreen to the screen, using Realscreen to avoid
  2781.  * unnecessary output. 
  2782.  */
  2783. void
  2784. updateRealscreen()
  2785. {
  2786.     register char  *np = Nextscreen;
  2787.     register char  *rp = Realscreen;
  2788.     register char  *endscreen;
  2789.     register int    row = 0, col = 0;
  2790.     int             gorow = -1, gocol = -1;
  2791.  
  2792.     if (RedrawingDisabled)
  2793.     return;
  2794.  
  2795.     if (!MustRedrawScreen && !MustRedrawLine)
  2796.     return;
  2797.  
  2798.     if (MustRedrawLine) {
  2799.     msg("internal error: updateRealscreen called when MustRedrawLine set");
  2800.     sleep(5);
  2801.     }
  2802.     endscreen = &np[(Rows - 1) * Columns];
  2803.  
  2804.     outstr(T_CI);        /* disable cursor */
  2805.  
  2806.     for (; np < endscreen; np++, rp++) {
  2807.     /* If desired screen (contents of Nextscreen) does not */
  2808.     /* match what's really there, put it there. */
  2809.     if (*np != *rp) {
  2810.         /* if we are positioned at the right place, */
  2811.         /* we don't have to use windgoto(). */
  2812.         if (gocol != col || gorow != row) {
  2813.         /*
  2814.          * If we're just off by one, don't send an entire esc. seq.
  2815.          * (this happens a lot!) 
  2816.          */
  2817.         if (gorow == row && gocol + 1 == col) {
  2818.             outchar(*(np - 1));
  2819.             gocol++;
  2820.         } else
  2821.             windgoto(gorow = row, gocol = col);
  2822.         }
  2823.         outchar(*rp = *np);
  2824.         gocol++;
  2825.     }
  2826.     if (++col >= Columns) {
  2827.         col = 0;
  2828.         row++;
  2829.     }
  2830.     }
  2831.  
  2832.     outstr(T_CV);        /* enable cursor again */
  2833.  
  2834.     MustRedrawLine = FALSE;
  2835.     MustRedrawScreen = FALSE;
  2836. }
  2837. SHAR_EOF
  2838. #    End of shell archive
  2839. exit 0
  2840. -- 
  2841. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2842. Have five nice days.
  2843.